
#include "Disc.h"
#include "Entity.h"

namespace p2 {

IMPLEMENT_RTT(p2, Disc);

/*virtual */
Disc::~Disc()
{
}

Disc* Disc::create(real mass, Vector2<real> position, real rotation, p2Material const& material, uint32 plane, void* userData)
{
	Disc* newDisc = _allocator.allocate(1);
	if (newDisc) {
		_allocator.construct(newDisc, Disc(mass, position, rotation, material, plane, userData));
	}
	return newDisc;
}

bool Disc::updateShapeData()
{
	if (_radius <= 0.f) {
		return false;
	}
	_volume = Math<real>::PI * _radius * _radius;
	_centerOfMass = Vector2<real>::ZERO;

	/*
	 * I = ( 1 / 2 ).m.(r.r)
	 */
	real I = (getMass() * (_radius * _radius)) / 2.f;
	setInertia(I);
	return true;
}

void Disc::updateMotionBounds(real64 dT)
{
	Vector4<real> fwx(Vector4<real>(Vector2<real>::ZERO) * Element::getFutureWorldMatrix(dT));
	_motionBounds.min().X() = fwx.X() - _radius;
	_motionBounds.max().X() = fwx.X() + _radius;
	_motionBounds.min().Y() = fwx.Y() - _radius;
	_motionBounds.max().Y() = fwx.Y() + _radius;
	_motionBounds.growToContain(_worldBounds);
}

void Disc::updateWorldSpace()
{
	updateTransform();
	_worldBounds.min().X() = _worldPosition.X() - _radius;
	_worldBounds.max().X() = _worldPosition.X() + _radius;
	_worldBounds.min().Y() = _worldPosition.Y() - _radius;
	_worldBounds.max().Y() = _worldPosition.Y() + _radius;
}

bool Disc::contains(Vector2<real> worldPoint)
{
	Vector2<real> p(worldPoint - _worldPosition);
	return ( p.squaredLength() <= (_radius * _radius) );
}

}
